using System.Collections.Generic;
using NFreeMarker.Template;
using NUnit.Framework;

// ReSharper disable InconsistentNaming
namespace NFreeMarker.Tests.Template
{
    public class TemplateTests_ProcessHashOperations
    {
        [TestFixture]
        public class When_concatenating_two_empty_hashes : TemplateTestsBase
        {
            [Test]
            public void Assure_the_resulting_hash_is_empty()
            {
                SetTemplateContent("${(hashA + hashB)?size}");
                AddTemplateVariable("hashA", new Dictionary<string, string>());
                AddTemplateVariable("hashB", new Dictionary<string, string>());

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("0"));
            }
        }

        [TestFixture]
        public class When_concatenating_one_empty_and_one_non_empty_hash : TemplateTestsBase
        {
            [Test]
            public void Assure_the_resulting_hash_contains_the_keys_from_the_non_emtpy_hash()
            {
                SetTemplateContent(
                    "<#list (hashA + hashB)?keys as key>" +
                    "[${key}]" +
                    "</#list>");
                AddTemplateVariable("hashA", new Dictionary<string, int>
                {
                    {"bob", 23}
                });
                AddTemplateVariable("hashB", new Dictionary<string, int>());

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("[bob]"));
            }

            [Test]
            public void Assure_the_resulting_hash_contains_the_values_from_the_non_empty_hash()
            {
                SetTemplateContent(
                    "<#list (hashA + hashB)?values as value>" +
                    "[${value}]" +
                    "</#list>");
                AddTemplateVariable("hashA", new Dictionary<string, int>
                {
                    {"bob", 23}
                });
                AddTemplateVariable("hashB", new Dictionary<string, int>());

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("[23]"));
            }
        }

        [TestFixture]
        public class When_concatenating_two_non_empty_hashes : TemplateTestsBase
        {
            [SetUp]
            public override void SetUp()
            {
                base.SetUp();

                AddTemplateVariable("hashA", new Dictionary<string, int>
                {
                    {"bob", 23}
                });
                AddTemplateVariable("hashB", new Dictionary<string, int>
                {
                    {"john", 42}
                });
            }

            [Test]
            public void Assure_the_resulting_hash_contains_the_keys_from_both_hashes()
            {
                SetTemplateContent(
                    "<#list (hashA + hashB)?keys as key>" +
                    "[${key}]" +
                    "</#list>");

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("[bob][john]"));
            }

            [Test]
            public void Assure_the_resulting_hash_contains_the_values_from_both_hashes()
            {
                SetTemplateContent(
                    "<#list (hashA + hashB)?values as value>" +
                    "[${value}]" +
                    "</#list>");

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("[23][42]"));
            }
        }

        [TestFixture]
        public class When_concatenating_two_non_empty_custom_hashes : TemplateTestsBase
        {
            [Test]
            public void Assure_the_resulting_hash_contains_the_elements_from_both_hashes()
            {
                SetTemplateContent(
                    "<#assign dict = hashA + hashB>" +
                    "[${dict['bob']}]" +
                    "[${dict['john']}]");
                AddTemplateVariable("hashA", new CustomHash("bob", "23"));
                AddTemplateVariable("hashB", new CustomHash("john", "42"));

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("[23][42]"));
            }

            private class CustomHash : ITemplateHashModel
            {
                private readonly string _key;
                private readonly string _value;

                public CustomHash(string key, string value)
                {
                    _key = key;
                    _value = value;
                }

                public ITemplateModel Get(string key)
                {
                    return (key == _key)
                               ? new SimpleScalar(_value)
                               : null;
                }

                public bool IsEmpty()
                {
                    return false;
                }
            }
        }
    }
}
// ReSharper enable InconsistentNaming
